package com.shen.llm;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.shen.utils.CsvFileUtil;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static com.shen.constant.CsvConstant.csvHeaders1;
import static com.shen.utils.ApiInvocationUtil.sendPostRequestWithHttpClient;

public class LLMToDict {

    private static int NUM = 50;

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        String csvReadFilePath = "E:\\city2000.csv";
        String csvWriteFilePath = "E:\\llm.csv";
        List<String> originalList = CsvFileUtil.readCsvFile(csvReadFilePath);
        List<String[]> resultList = new ArrayList<>();
        int batchSize = NUM;
        for (int i = 0; i < originalList.size(); i += batchSize) {
            int toIndex = Math.min(i + batchSize, originalList.size());
            List<String> batch = originalList.subList(i, toIndex);

            System.out.printf("批次 %d: 元素索引 %d-%d，共 %d 个元素%n", (i / batchSize) + 1, i, toIndex - 1, batch.size());
            System.out.println("内容: " + batch);
            System.out.println("---");

            List<String[]> strings = mergeResults(batch);
            resultList.addAll(strings);
        }
        CsvFileUtil.writeCsvFile1(csvWriteFilePath, resultList, csvHeaders1);
    }


    public static List<String[]> mergeResults(List<String> batch) throws InterruptedException, ExecutionException {
        // 创建线程池（根据接口数量调整）
        ExecutorService executor = Executors.newFixedThreadPool(8);

        // 统一信用代码
        CompletableFuture<List<String[]>> future1 = CompletableFuture.supplyAsync(() -> getLLMs(batch, "app-KemWPjr2CTbi4WTER2H0VifC"), executor);

        // 保密业务范畴
        CompletableFuture<List<String[]>> future2 = CompletableFuture.supplyAsync(() -> getLLMs(batch, "app-mqkztxIFRLVXde6lYVFWhc2h"), executor);

        // 机构大类
        CompletableFuture<List<String[]>> future3 = CompletableFuture.supplyAsync(() -> getLLMs(batch, "app-yqfD0yFron264NfZxmF1gQiX"), executor);

        // 所属类别
        CompletableFuture<List<String[]>> future4 = CompletableFuture.supplyAsync(() -> getLLMs(batch, "app-LW9mzIo9DOuR8UntRqojG8Pg"), executor);

        // 单位资质类型
        CompletableFuture<List<String[]>> future5 = CompletableFuture.supplyAsync(() -> getLLMs(batch, "app-XgC2eAoAo9HJZruqEgwSC8G9"), executor);

        // 机构层级
        CompletableFuture<List<String[]>> future6 = CompletableFuture.supplyAsync(() -> getLLMs(batch, "app-ZvLpl2iqxKzZ5Tu3w3FKAmFA"), executor);

        // 所属领域
        CompletableFuture<List<String[]>> future7 = CompletableFuture.supplyAsync(() -> getLLMs(batch, "app-sIiNBlle3MgZrIIBnwPWEU4X"), executor);

        // 机构小类
        CompletableFuture<List<String[]>> future8 = CompletableFuture.supplyAsync(() -> getLLMs(batch, "app-jnOZVfQ3TcQKEcnDXkPfo3k2"), executor);

        // 等待所有任务完成
        CompletableFuture<Void> allFutures = CompletableFuture.allOf(future1, future2, future3, future4, future5, future6, future7, future8);

        // 合并结果
        CompletableFuture<List<String[]>> mergedResult = allFutures.thenApply(v -> {
            try {
                List<List<String[]>> allResults = Stream.of(future1.get(), future2.get(), future3.get(), future4.get(), future5.get(), future6.get(), future7.get(), future8.get()).collect(Collectors.toList());

                // 验证所有列表长度一致
                int size = NUM;
                for (List<String[]> list : allResults) {
//                    if (list.size() != size) {
//                        throw new IllegalArgumentException("所有列表必须具有相同的长度");
//                    }
                    while (list.size() < size) {
                        // 创建一个新的String数组，用特殊字符填充
                        String[] newElement = new String[list.isEmpty() ? 0 : list.get(0).length];
                        Arrays.fill(newElement, "*****");
                        list.add(newElement);
                    }
                }

                // 合并每个位置的数组
                List<String[]> mergedList = new ArrayList<>(size);
                for (int i = 0; i < size; i++) {
                    String[] mergedArray = new String[16];
                    int index = 0;

                    // 依次将每个方法返回的数组元素复制到新数组
                    for (List<String[]> list : allResults) {
                        String[] arr = list.get(i);
//                        if (arr.length != 2) {
//                            throw new IllegalArgumentException("每个内部数组长度必须为2");
//                        }

//                        if (arr.length < 2) {
//                            // 创建新数组并复制原内容
//                            String[] newArr = new String[2];
//                            System.arraycopy(arr, 0, newArr, 0, arr.length);
//                            // 补充特殊字符到剩余位置
//                            for (int j = arr.length; j < 2; j++) {
//                                newArr[j] = "***********";
//                            }
//                            System.arraycopy(newArr, 0, mergedArray, index, 2);
//                            // 替换原数组
//                            // list.set(i, newArr);
//                        } else if (arr.length > 2) {
//                            // 可选：如果需要截断超长数组
//                            String[] newArr = Arrays.copyOf(arr, 2);
//                            System.arraycopy(newArr, 0, mergedArray, index, 2);
//                            //  list.set(i, newArr);
//                        } else {
//                            System.arraycopy(arr, 0, mergedArray, index, 2);
//                        }
                        System.arraycopy(arr, 0, mergedArray, index, 2);
                        index += 2;
                    }
                    mergedList.add(mergedArray);
                }
                return mergedList;
            } catch (Exception e) {
                throw new RuntimeException("合并结果失败", e);
            }
        });

        return mergedResult.get();
    }

    public static List<String[]> getLLMs(List<String> orgs, String key) {
        List<String[]> strings = null;
        try {
            StringBuilder sb = new StringBuilder();
            for (String element : orgs) {
                sb.append(element).append("/n");
            }
            String orgStr = sb.toString();

            // 示例URL和请求体  "用户需求"
            String apiUrl = "http://47.115.218.172:18190/v1/workflows/run";
            String requestBody = "{ \"inputs\": { \"jgmc\": \"" + orgStr + "\"},\"response_mode\": \"blocking\", \"user\": \"case_workflow\"}";
            System.out.println("key: " + key);
            // 使用Apache HttpClient发送POST请求
            String postResponseHttpClient = sendPostRequestWithHttpClient(apiUrl, requestBody, key);
            System.out.println("HttpClient POST响应内容: " + postResponseHttpClient);

            // 处理JSON响应
            strings = parseJsonResponse(postResponseHttpClient);
            System.out.println("解析后的响应: " + strings);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return strings;
    }

    // 处理JSON响应的示例方法
    public static List<String[]> parseJsonResponse(String jsonResponse) {
        // 这里应该使用JSON解析库，如Jackson或Gson
        JSONObject jsonObject = JSONObject.parseObject(jsonResponse);
        JSONObject data = jsonObject.getJSONObject("data");
        List<String[]> strings = new ArrayList<>();
        if (data.getString("status").equals("succeeded")) {
            JSONObject outputs = data.getJSONObject("outputs");
            String result = outputs.getString("result");

            // 解析JSON数组
            JSONArray jsonArray = JSON.parseArray(result);

            for (int i = 0; i < jsonArray.size(); i++) {
                String[] llmResult = new String[2];
                JSONObject obj = jsonArray.getJSONObject(i);
                if (obj.containsKey("key")) {
                    llmResult[0] = obj.getString("key");
                } else {
                    llmResult[0] = obj.getString("org_name");
                }
                llmResult[1] = obj.getString("value");
                strings.add(llmResult);
            }
        }
        return strings;
    }
}
